/******************************************************************************
Project    : Real time rtsp server library base on live555
*******************************************************************************
File Name    :  <Mp2TsRTimeServerMediaSubsession.cpp>:  mp2ts real time SMSS source file
Module Name  :  
Description  :  None
History      :
 No.   Ver.     Date        Designed by  Comment
-----+--------+----------+------------+---------------------------------------
 001   0.00.01  06/04/2015  <3G@LIURENHUA>   <mp2ts real time SMSS source file>
*******************************************************************************/
#include <pthread.h>
#include "Mp2TsRTimeFramedSource.h"
#include "Mp2TsRTimeServerMediaSubsession.h"

/******************************************************************************
  macro define
 ******************************************************************************/
#define TRANSPORT_PACKET_SIZE 188
#define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7
#define CHUNK_SIZE	\
	(TRANSPORT_PACKET_SIZE * TRANSPORT_PACKETS_PER_NETWORK_PACKET)

/******************************************************************************
  class functions define
 ******************************************************************************/
Mp2TsRTimeServerMediaSubsession * Mp2TsRTimeServerMediaSubsession::createNew(
							UsageEnvironment & env, 
#ifdef LOCAL_SOCK_INPUT
							const char  *pcIdentity,
							const u_int32_t unSBufSize, 
							const u_int32_t unRBufSize
#else
							queue_t *pstQue
#endif /* LOCAL_SOCK_INPUT */
							)
{
	return new Mp2TsRTimeServerMediaSubsession(env,
#ifdef LOCAL_SOCK_INPUT
							pcIdentity, 
							unSBufSize,
							unRBufSize
#else
							pstQue
#endif /* LOCAL_SOCK_INPUT */
							);
}

Mp2TsRTimeServerMediaSubsession::Mp2TsRTimeServerMediaSubsession(
							UsageEnvironment & env,
#ifdef LOCAL_SOCK_INPUT
							const char  *pcIdentity,
							const u_int32_t unSBufSize, 
							const u_int32_t unRBufSize
#else
							queue_t *pstQue
#endif /* LOCAL_SOCK_INPUT */
							) : OnDemandServerMediaSubsession(env, True)
{
#ifdef LOCAL_SOCK_INPUT
	/* Local socket identity checking */
	if( (NULL != pcIdentity) ){
		snprintf(m_cIdentity, LSOCK_ID_LENGTH, "%s", pcIdentity);
	}else{
		int nSMSSCnt = 0;
		pthread_mutex_lock(&gMutex);
		nSMSSCnt = gSMSSCnt++;
		pthread_mutex_unlock(&gMutex);
		snprintf(m_cIdentity, LSOCK_ID_LENGTH, 
			"%s_ch%d", LOCAL_SOCKET_ID, nSMSSCnt);
		rtsp_db_info("ID=%s", m_cIdentity);
	}
	m_unSBufSize = unSBufSize;
	rtsp_db_info("m_unSBufSize=%d", m_unSBufSize);
	m_unRBufSize = unRBufSize;
	rtsp_db_info("m_unRBufSize=%d", m_unRBufSize);
#else
	m_que = pstQue;
#endif /* LOCAL_SOCK_INPUT */
}

FramedSource *
	Mp2TsRTimeServerMediaSubsession::createNewStreamSource(
	unsigned clientSessionId, unsigned & estBitrate)
{
	FramedSource *pctFrmSource = NULL;
	//estBitrate = 5000; // kbps, estimate
	
	pctFrmSource = 
		MPEG2TransportStreamFramer::createNew(
 		envir(), 
 		Mp2TsRTimeFramedSource::createNew(
 		envir(), 
 #ifdef LOCAL_SOCK_INPUT
 		m_cIdentity, 
 		m_unSBufSize, 
 		m_unRBufSize, 
 #else
 		m_que,
 #endif /* LOCAL_SOCK_INPUT */
 		CHUNK_SIZE));

	return pctFrmSource;
}

RTPSink *Mp2TsRTimeServerMediaSubsession::createNewRTPSink(
	Groupsock * rtpGroupsock, 
	unsigned char rtpPayloadTypeIfDynamic, 
	FramedSource * inputSource)
{
	RTPSink *pctRtpSink = 
		SimpleRTPSink::createNew(
		envir(), rtpGroupsock, 
		rtpPayloadTypeIfDynamic, 
		90000, "video", "MP2T", 1, True, False);
	return pctRtpSink;
}
